package com.park.user.service.user.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.park.comm.ResultEnum;
import com.park.comm.WxComm;
import com.park.dao.mapper.user.UserMapper;
import com.park.entity.user.UserInfo;
import com.park.entity.user.UserLoginVo;
import com.park.entity.wx.*;
import com.park.exception.CommException;
import com.park.jwt.TokenUtils;
import com.park.user.service.user.UserService;
import com.park.utils.wx.WxUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author Administrator
 * @title: UserServiceImpl
 * @projectName park
 * @description: 用户业务类接口实现
 * @date 2020/5/120:31
 */
@Service(value = "userService")
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    private static Lock lock = new ReentrantLock();

    public List<UserInfo> getALLUser() {
        return userMapper.getALLUser();
    }

    /**
     　　* @description: 微信登录获取code，去请求code2Session,得到 换取 用户唯一标识 OpenID 和 会话密钥 session_key
     　　* @param [wxLoginParam ]
     　　* @return UserLoginVo
     　　* @throws
     　　* @author ZhangHaiWen
     　　* @version 2.0
     　　* @date 2020/5/2 9:36
     　　*/
    public UserLoginVo login(WxLoginParam wxLoginParam) {
        lock.lock();
        try {
            String jsCode = wxLoginParam.getJsCode();
            if(StrUtil.isBlank(jsCode)){
                throw new CommException(ResultEnum.WX_CODE_EMPTY_ERROR);
            }
            Code2SessionReturnData code2SessionReturnData = WxUtils.code2Session(WxComm.USER_APPID, WxComm.USER_SECRET, jsCode);
            int userId = 0;
            if(code2SessionReturnData.checkCode()){
                String openid = code2SessionReturnData.getOpenid();
                UserInfo userInfo = userMapper.getUserInfoByOpenId(openid);
                if(ObjectUtil.isNotEmpty(userInfo)){
                    //登录
                    String sessionKey = code2SessionReturnData.getSession_key();
                    long timeStamp = System.currentTimeMillis();
                    userInfo.setTimeStamp(timeStamp);
                    userInfo.setSessionKey(sessionKey);
                    userMapper.updateByPrimaryKeySelective(userInfo);
                }else{
                    //注册
                    String sessionKey = code2SessionReturnData.getSession_key();
                    String unionid = code2SessionReturnData.getUnionid();
                    long timeStamp = System.currentTimeMillis();
                    userInfo = new UserInfo();
                    userInfo.setSessionKey(sessionKey);
                    userInfo.setUnionId(unionid);
                    userInfo.setOpenId(openid);
                    userInfo.setAddTimeStamp(timeStamp);
                    userInfo.setTimeStamp(timeStamp);
                    userMapper.insert(userInfo);
                }
                //获取用户主键
                userId = userInfo.getId();
            }
            //生成用户Token
            String tokenWithClaim = TokenUtils.createTokenWithClaim(userId);
            UserLoginVo userLoginVo = new UserLoginVo();
            userLoginVo.setUserId(userId);
            userLoginVo.setSignatureToken(tokenWithClaim);
            return userLoginVo;
        }finally {
            lock.unlock();
        }

    }

    /**
     　　* @description:
     　　* @param [wxEncryptedDataParam]
     　　* @return
     　　* @throws
     　　* @author ZhangHaiWen
     　　* @version 2.0
     　　* @date 2020/5/2 11:40
     　　*/
    public void getPhoneNumber(WxEncryptedDataParam wxEncryptedDataParam) {
        Integer userId = wxEncryptedDataParam.getUserId();
        UserInfo userInfo = userMapper.selectByPrimaryKey(userId);
        if(ObjectUtil.isNotEmpty(userInfo)){
            String sessionKey = userInfo.getSessionKey();
            String encryptedData = wxEncryptedDataParam.getEncryptedData();
            String vi = wxEncryptedDataParam.getVi();
            PhoneNumberReturnData phoneNumberReturnData = WxUtils.getPhoneNumber(encryptedData, sessionKey, vi);
            String phoneNumber = phoneNumberReturnData.getPhoneNumber();
            userInfo.setPhoneNumber(phoneNumber);
            userInfo.setTimeStamp(System.currentTimeMillis());
            userMapper.updateByPrimaryKeySelective(userInfo);
        }
    }

    /**
     　　* @description:
     　　* @param [wxUserInfoParam]
     　　* @return
     　　* @throws
     　　* @author ZhangHaiWen
     　　* @version 2.0
     　　* @date 2020/5/2 11:40
     　　*/
    public void getUserInfo(WxUserInfoParam wxUserInfoParam) {
        String rawData = wxUserInfoParam.getRawData();
        String signature = wxUserInfoParam.getSignature();
        Integer userId = wxUserInfoParam.getUserId();
        String vi = wxUserInfoParam.getVi();
        String encryptedData = wxUserInfoParam.getEncryptedData();
        UserInfo userInfo = userMapper.selectByPrimaryKey(userId);
        if(ObjectUtil.isNotEmpty(userInfo)){
            //校验 signature  使用等量算法
            if(signature.equals(WxUtils.getSignature(rawData,userInfo.getSessionKey()))){
                String sessionKey = userInfo.getSessionKey();
                UserInfoReturnData userInfoReturnData = WxUtils.getUserInfo(encryptedData, sessionKey, vi);
                String avatarUrl = userInfoReturnData.getAvatarUrl();
                String city = userInfoReturnData.getCity();
                String country = userInfoReturnData.getCountry();
                String gender = userInfoReturnData.getGender();
                String language = userInfoReturnData.getLanguage();
                String province = userInfoReturnData.getProvince();
                String openId = userInfoReturnData.getOpenId();
                String unionId = userInfoReturnData.getUnionId();
                String nickName = userInfoReturnData.getNickName();
                // 更新用户信息
                userInfo.setTimeStamp(System.currentTimeMillis());
                userInfo.setNickName(nickName);
                userInfo.setAvatarUrl(avatarUrl);
                userInfo.setGender(gender);
                userMapper.updateByPrimaryKeySelective(userInfo);
            }
        }
    }

}
